#include "projectmodel.h"

ProjectModel::ProjectModel(QObject *parent) : QAbstractItemModel(parent)
{
   this->_rootDir = 0;
}

UmlDirItem* ProjectModel::projectData()
{
    return this->_rootDir;
}

void ProjectModel::setProjectData(UmlDirItem *rootDir)
{
    this->_rootDir = rootDir;
    this->reset();
}

int ProjectModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column() > 0 || this->_rootDir == 0) {
        return 0;
    }

    if (!parent.isValid()) {
        UmlDirItem *dir = this->_rootDir;
        return dir->childCount();
    } else {
        UmlGraphicsItem *item = static_cast<UmlGraphicsItem*>(parent.internalPointer());
        if (item->isOfType(UmlItem::UmlPackageItemType)) {
            UmlDirItem *dir = static_cast<UmlDirItem*>(item);
            return dir->childCount();
        }
    }

    return 0;
}

int ProjectModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);

    return 1;
}

QVariant ProjectModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return QVariant();
    }

    if (role == Qt::DisplayRole) {
        UmlItem *item = static_cast<UmlGraphicsItem*>(index.internalPointer());
        return item->name();
    }

    if (role == Qt::DecorationRole) {
        UmlGraphicsItem *item = static_cast<UmlGraphicsItem*>(index.internalPointer());

        if (item->isOfType(UmlItem::UmlClassItemType)) {
            UmlClassItem *classItem = static_cast<UmlClassItem*>(item);

            if (classItem->isAbstract()) {
                return QIcon(":/icons/packagebrowser/absclass.png");
            }
            else if (classItem->isInterface()) {
                return QIcon(":/icons/packagebrowser/interface.png");
            }
            else {
                return QIcon(":/icons/packagebrowser/class.png");
            }
        }
        else if (item->isOfType(UmlItem::UmlPackageItemType)) {
            return QIcon(":/icons/packagebrowser/package.png");
        }
    }

    if (role == Qt::SizeHintRole) {
        return QSize(32, 32);
    }

    return QVariant();
}

QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!this->hasIndex(row, column, parent)) {
        return QModelIndex();
    }

    UmlGraphicsItem *item;

    if (!parent.isValid()) {
        item = this->_rootDir;
    } else {
        item = static_cast<UmlGraphicsItem*>(parent.internalPointer());
    }

    if (item->isOfType(UmlItem::UmlPackageItemType)) {
        UmlDirItem *dir = static_cast<UmlDirItem*>(item);
        UmlGraphicsItem *child = dir->child(row);
        return this->createIndex(row, column, child);
    } else {
        return QModelIndex();
    }
}

QModelIndex ProjectModel::parent(const QModelIndex &child) const
{
    if (!child.isValid()) {
        return QModelIndex();
    }

    UmlGraphicsItem *childItem = static_cast<UmlGraphicsItem*>(child.internalPointer());
    UmlDirItem *parent = childItem->parentDir();

    if (parent == this->_rootDir) {
        return QModelIndex();
    }

    return this->createIndex(parent->row(), 0, parent);
}

QModelIndex ProjectModel::createIndex(int row, int column, void *data) const
{
    QModelIndex index = QAbstractItemModel::createIndex(row, column, data);

    UmlGraphicsItem* item = static_cast<UmlGraphicsItem*>(data);
    item->setModelIndex(index);

    return index;
}

void ProjectModel::insertItem(UmlDirItem *dir, UmlGraphicsItem *item)
{
    QModelIndex parentIndex = dir->modelIndex();

    this->beginInsertRows(parentIndex, dir->childCount(), dir->childCount());
    dir->appendChild(item);
    this->endInsertRows();
}

void ProjectModel::removeItem(UmlGraphicsItem *item)
{
    UmlDirItem *parent = item->parentDir();
    QModelIndex parentIndex = parent->modelIndex();

    this->beginRemoveRows(parentIndex, item->row(), item->row());
    parent->removeChild(item);
    this->endRemoveRows();
}
